﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web.Mvc;
using ControleRepresentante.Logic.Models;
using ControleRepresentante.Logic.Repositories;
using ControleRepresentante.Logic.Statistics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebSite.Controllers;

namespace ControleRepresentante.UnitTests
{
    public static class TestScenarioVendedorHelper
    {
        public static void DeleteVendedor(this TestScenario testScenario, Guid vendedorId)
        {
            IVendedorRepository vendedorRepository = testScenario.RepositoryProvider.GetRepository<IVendedorRepository>();
            StatisticsBase statistics;
            int countBefore = vendedorRepository.GetModels(out statistics).Count();
            using (VendedorController vendedorController = new VendedorController(testScenario.RepositoryProvider, testScenario.SessionConfiguration, testScenario.ControllerExtensionProvider, testScenario.ImpostProvider))
            {
                vendedorController.Delete(vendedorId);
                vendedorController.Delete(vendedorId, null);
                Assert.AreEqual(countBefore - 1, vendedorRepository.GetModels(out statistics).Count());
            }
        }

        public static Guid CreateVendedor(this TestScenario testScenario, Vendedor vendedor)
        {
            IVendedorRepository vendedorRepository = testScenario.RepositoryProvider.GetRepository<IVendedorRepository>();
            StatisticsBase statistics;
            int countBefore = vendedorRepository.GetModels(out statistics).Count();
            using (VendedorController vendedorController = new VendedorController(testScenario.RepositoryProvider, testScenario.SessionConfiguration, testScenario.ControllerExtensionProvider, testScenario.ImpostProvider))
            {
                vendedorController.Create();
                foreach (Contato contato in vendedor.Contatos)
                {
                    vendedorController.ContatoInsert(contato.Tipo.ToString(), contato.Valor, contato.Observacao, contato.Principal);
                }
                foreach (Conta conta in vendedor.Contas)
                {
                    vendedorController.ContaInsert(conta.Banco, conta.Agencia, conta.Numero, conta.Observacao, conta.Principal);
                }
                foreach (Endereco endereco in vendedor.Enderecos)
                {
                    vendedorController.EnderecoInsert(endereco.Tipo.ToString(), endereco.Rua, endereco.Numero,
                                                      endereco.Complemento, endereco.Bairro, endereco.CEP,
                                                      endereco.Cidade, endereco.Estado, endereco.Observacao, endereco.Principal);
                }
                NameValueCollection collection = new NameValueCollection();
                foreach (AttributeValue attributeValue in vendedor.AttributeValues)
                {
                    collection.Add("_" + attributeValue.Attribute.Name, attributeValue.Value);
                }
                FormCollection formCollection = new FormCollection(collection);
                ActionResult actionResult = vendedorController.Create(vendedor.Nome, vendedor.Nascimento, vendedor.CPF,
                                                                      vendedor.Identidade, formCollection);
                Assert.IsInstanceOfType(actionResult, typeof(RedirectToRouteResult));
                RedirectToRouteResult redirectToRouteResult = (RedirectToRouteResult)actionResult;
                Assert.AreEqual("Details", redirectToRouteResult.RouteValues["action"]);
                IEnumerable<Vendedor> vendedores = vendedorRepository.GetModels(out statistics);
                Assert.AreEqual(countBefore + 1, vendedores.Count());
                Vendedor addedVendedor = vendedores.FirstOrDefault(x => x.Nome == vendedor.Nome);
                Assert.AreEqual(addedVendedor.Id, redirectToRouteResult.RouteValues["id"]);
                Assert.AreEqual(vendedor.Nome, addedVendedor.Nome);
                Assert.AreEqual(vendedor.Nascimento, addedVendedor.Nascimento);
                Assert.AreEqual(vendedor.CPF, addedVendedor.CPF);
                Assert.AreEqual(vendedor.Identidade, addedVendedor.Identidade);
                Assert.AreEqual(vendedor.Contatos.Count(), addedVendedor.Contatos.Count());
                foreach (Contato contato in vendedor.Contatos)
                {
                    Contato addedContato = addedVendedor.Contatos.Single(x => x.Valor == contato.Valor);
                    Assert.AreEqual(contato.Tipo, addedContato.Tipo);
                    Assert.AreEqual(contato.Valor, addedContato.Valor);
                    Assert.AreEqual(contato.Observacao, addedContato.Observacao);
                    Assert.AreEqual(contato.Principal, addedContato.Principal);
                }
                Assert.AreEqual(vendedor.Contas.Count(), addedVendedor.Contas.Count());
                foreach (Conta conta in vendedor.Contas)
                {
                    Conta addedConta = addedVendedor.Contas.Single(x => x.Numero == conta.Numero);
                    Assert.AreEqual(conta.Agencia, addedConta.Agencia);
                    Assert.AreEqual(conta.Banco, addedConta.Banco);
                    Assert.AreEqual(conta.Numero, addedConta.Numero);
                    Assert.AreEqual(conta.Observacao, addedConta.Observacao);
                    Assert.AreEqual(conta.Principal, addedConta.Principal);
                }
                Assert.AreEqual(vendedor.Enderecos.Count(), addedVendedor.Enderecos.Count());
                foreach (Endereco endereco in vendedor.Enderecos)
                {
                    Endereco addedEndereco = addedVendedor.Enderecos.Single(x => x.Rua == endereco.Rua);
                    Assert.AreEqual(endereco.Tipo, addedEndereco.Tipo);
                    Assert.AreEqual(endereco.Rua, addedEndereco.Rua);
                    Assert.AreEqual(endereco.Numero, addedEndereco.Numero);
                    Assert.AreEqual(endereco.Complemento, addedEndereco.Complemento);
                    Assert.AreEqual(endereco.Bairro, addedEndereco.Bairro);
                    Assert.AreEqual(endereco.CEP, addedEndereco.CEP);
                    Assert.AreEqual(endereco.Cidade, addedEndereco.Cidade);
                    Assert.AreEqual(endereco.Estado, addedEndereco.Estado);
                    Assert.AreEqual(endereco.Observacao, addedEndereco.Observacao);
                    Assert.AreEqual(endereco.Principal, addedEndereco.Principal);
                }
                Assert.AreEqual(vendedor.AttributeValues.Count(), addedVendedor.AttributeValues.Count());
                foreach (AttributeValue attributeValue in vendedor.AttributeValues)
                {
                    AttributeValue addedAttributeValue = addedVendedor.AttributeValues.Single(x => x.Attribute.Name == attributeValue.Attribute.Name);
                    Assert.AreEqual(attributeValue.Value, addedAttributeValue.Value);
                }
                return addedVendedor.Id;
            }
        }

        internal static Guid CreateVendedor(this TestScenario testscenario, string nome)
        {
            return testscenario.CreateVendedor(new Vendedor {Nome = nome});
        }
    }
}